#include "NamedPipeServer.h"

#pragma comment( lib, "user32.lib" )

NamedPipeServer::NamedPipeServer(std::string pipeName, int id ) : m_readBuffer(new char[256]), m_bufferSize(256)
{
	std::stringstream ss;
	ss<<pipeName<<id;
	std::string strFullPipeName=ss.str();
	TCHAR *LPCTSTRpipename=new TCHAR[strFullPipeName.size()+sizeof(TCHAR)*1];
	LPCTSTRpipename[strFullPipeName.size()]=(TCHAR)'\0';
	std::copy(strFullPipeName.begin(),strFullPipeName.end(),LPCTSTRpipename);

	m_pipe = CreateNamedPipe(LPCTSTRpipename,
		PIPE_ACCESS_DUPLEX,
		PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
		1, 0, 256, 200, 0);
	
}
NamedPipeServer::NamedPipeServer(std::string pipeName) : m_readBuffer(new char[256]), m_bufferSize(256)
{
	int id=0;
	m_pipe=INVALID_HANDLE_VALUE;
	while(INVALID_HANDLE_VALUE == m_pipe){		
		std::stringstream ss;
		ss<<pipeName<<id;
		std::string strFullPipeName=ss.str();
		TCHAR *LPCTSTRpipename=new TCHAR[strFullPipeName.size()+sizeof(TCHAR)*1];
		LPCTSTRpipename[strFullPipeName.size()]=(TCHAR)'\0';
		std::copy(strFullPipeName.begin(),strFullPipeName.end(),LPCTSTRpipename);

		m_pipe = CreateNamedPipe(LPCTSTRpipename,
			PIPE_ACCESS_DUPLEX,
			PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
			1, 0, 256, 200, 0);	
		id++;
	}
	
}
NamedPipeServer::~NamedPipeServer()
{	
	Destroy();
}

bool NamedPipeServer::IsCreated()
{
	return m_pipe != INVALID_HANDLE_VALUE;
}

bool NamedPipeServer::IsBroken()
{
	DWORD lastError;
	PeekNamedPipe(m_pipe, NULL, (DWORD)0,NULL, NULL, NULL);	
	lastError = GetLastError();

	return lastError == ERROR_BROKEN_PIPE;
	
}
void NamedPipeServer::Destroy()
{
	if(m_readBuffer)
	{
		delete[] m_readBuffer;
		m_readBuffer = 0;
		m_bufferSize = 0;
	}

	if(m_pipe != INVALID_HANDLE_VALUE)
	{
		DisconnectNamedPipe(m_pipe);
		CloseHandle(m_pipe);
		m_pipe = INVALID_HANDLE_VALUE;
	}
}

bool NamedPipeServer::IsDataAvailable()
{
	DWORD numBytesInMessage;	
	
	if(NULL!= PeekNamedPipe(m_pipe, NULL, (DWORD)0,NULL, NULL, &numBytesInMessage) ){
		if(numBytesInMessage>0){
			return true;
		}
		
	}
	return FALSE;
}


bool NamedPipeServer::Read(std::string& message)
{
	DWORD numBytesInMessage;	

	if(PeekNamedPipe(m_pipe, NULL, 0, NULL, NULL, &numBytesInMessage ))
	{		
		// The extra character is used for a NULL terminator
		if(m_bufferSize < numBytesInMessage +1 )
		{
			delete[] m_readBuffer;
			m_readBuffer = new char[numBytesInMessage +1 ];
			m_bufferSize = numBytesInMessage +1;
		}

		DWORD numBytesRead;
		if(ReadFile(m_pipe, m_readBuffer, numBytesInMessage , &numBytesRead, 0))
		{
			m_readBuffer[numBytesInMessage] = '\0';
			message = m_readBuffer;
			return true;
		}
	}

	return false;
}
